package wangjg.pj.zkmanager.action;

import java.io.StringWriter;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * @author wangjg
 */
@Controller
public class NodeAction {
	@Autowired
	private ZooKeeperOpt zooKeeperOpt;
	
	@RequestMapping({"/zkinfo"})
	public void zkinfo(HttpServletResponse response) throws Exception{
		String data ="{\"userRoot\":\"/app\"}";
		response.getWriter().write("{\"code\":\"0000\",\"data\":"+data+"}");
	}
	
	@RequestMapping("/exe-{cmd}/**")
	public void execute1(@PathVariable String cmd, HttpServletRequest request, HttpServletResponse response) throws Exception{
		this.execute(cmd, request, response);
	}
	
	@RequestMapping("/zk/**")
	public void execute(String method, HttpServletRequest request, HttpServletResponse response) throws Exception{
		if("getChildren".equals(method)){
			try{
				this.getChildren(request, response);
			}catch(Exception e){
				response.getWriter().write("<error msg=\""+e.getMessage()+"\"/>");
			}
		}else if("add".equals(method)){
			this.add(request, response);
		}else if("del".equals(method)){
			this.del(request, response);
		}else if("setData".equals(method)){
			this.setData(request, response);
		}else if("getData".equals(method)){
			this.getData(request, response);
		}
	}

	private void getChildren(HttpServletRequest request, HttpServletResponse response) throws Exception{
		String path = this.getZkPath(request);
		
		String servletPath = request.getServletPath();
		if(!servletPath.endsWith("/")){
			servletPath += '/';
		}
		
		List<String> list = zooKeeperOpt.getChildren(path);
		
		DocumentBuilder dbd = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document doc = dbd.newDocument();
		Element root = doc.createElement("tree");
		doc.appendChild(root);
		
		for(String subPath:list){
			Element node = doc.createElement("tree");
			node.setAttribute("text", subPath);
			node.setAttribute("src", request.getContextPath()+servletPath+subPath+"?method=getChildren");
			node.setAttribute("action", "javascript:menuAction()");
			root.appendChild(node);
		}
	
		//set up a transformer
		TransformerFactory transfac = TransformerFactory.newInstance();
		Transformer trans = transfac.newTransformer();
		trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
		trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
		trans.setOutputProperty(OutputKeys.INDENT, "yes");
	
		//create string from xml tree
		StringWriter sw = new StringWriter();
		StreamResult result = new StreamResult(sw);
		DOMSource source = new DOMSource(doc);
		trans.transform(source, result);
		String xmlString = sw.toString();
		
		response.setContentType("text/xml");
		response.getWriter().write(xmlString);
	}

	private void add(HttpServletRequest request, HttpServletResponse response) throws Exception{
		String path = this.getZkPath(request);
		String nodeName = request.getParameter("nodeName");
		String newPath = path + (path.endsWith("/")?"":"/") + nodeName;
		zooKeeperOpt.create(newPath, null);
		response.getWriter().write("{\"code\":\"0000\"}");
	}

	private void del(HttpServletRequest request, HttpServletResponse response) throws Exception{
		String path = this.getZkPath(request);
		zooKeeperOpt.delete(path);
		response.getWriter().write("{\"code\":\"0000\"}");
	}
	
	private void setData(HttpServletRequest request, HttpServletResponse response) throws Exception{
		String path = this.getZkPath(request);
		String str = request.getParameter("data");
		byte[] data = null;
		if(str!=null){
			data = str.getBytes("UTF-8");
		};
		zooKeeperOpt.setData(path, data);
		response.getWriter().write("{\"code\":\"0000\"}");
	}
	
	private void getData(HttpServletRequest request, HttpServletResponse response) throws Exception{
		String path = this.getZkPath(request);
		byte[] data = zooKeeperOpt.getData(path);
		String str = "";
		if(data!=null){
			str = new String(data);
			str = str.replaceAll("\"", "\\\\\"");
		}
		response.getWriter().write("{\"code\":\"0000\",\"data\":\""+str+"\"}");
	}
	
	private String getZkPath(HttpServletRequest request){
		String path = request.getServletPath();
		int pos = path.indexOf('/', 1);
		path = path.substring(pos);
		if(path.endsWith("/")){
			path = path.substring(0, path.length()-1);
		}
		if(!path.startsWith("/")){
			path = "/"+path;
		}
		return path;
	}

}


